package com.kun.web.controller.activiti;

import cn.hutool.core.util.BooleanUtil;
import com.kun.domain.FormData;
import com.kun.dto.FormDataDto;
import com.kun.dto.IFormDataDto;
import com.kun.dto.TaskDto;
import com.kun.service.service.IFormDataService;
import com.kun.service.service.ITaskService;
import com.kun.utils.AjaxResult;
import com.kun.vo.TaskVo;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.CompleteTaskPayloadBuilder;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/task")
public class TaskController {

    private final TaskRuntime taskRuntime;

    private final ITaskService taskService;

    private final IFormDataService formDataService;

    public TaskController(TaskRuntime taskRuntime, ITaskService taskService, IFormDataService formDataService) {
        this.taskRuntime = taskRuntime;
        this.taskService = taskService;
        this.formDataService = formDataService;
    }

    /**
     * 获取我的代办任务
     */
    @GetMapping("/my-tasks")
    public ResponseEntity<AjaxResult> getMyTasks(TaskDto taskDto) {
        return AjaxResult.success(taskService.myTasks(taskDto));
    }

    /**
     * 完成任务
     */
    @PostMapping("/complete")
    public ResponseEntity<AjaxResult> completeTask(@Valid @RequestBody TaskVo taskVo) {
        return AjaxResult.success(taskService.completeTask(taskVo.getId()));
    }

    /**
     * 渲染动态表单
     */
    @GetMapping("/dynamic")
    public ResponseEntity<AjaxResult> getDynamicForm(String taskId) {
        return AjaxResult.success(taskService.getDynamicForm(taskId));
    }

    /**
     * 保存动态表单
     */
    @Transactional
    @PostMapping("/save-form-data")
    public ResponseEntity<String> saveDynamicForm(@RequestBody @Validated IFormDataDto formDataDto) {
        // task
        Task task = taskRuntime.task(formDataDto.getTaskId());
        String processDefinitionId = task.getProcessDefinitionId();
        String processInstanceId = task.getProcessInstanceId();
        String formKey = task.getFormKey();
        List<FormDataDto> formDataDtos = formDataDto.getFormDataDtos();

        // 查询历史表单
        FormData formData = new FormData();
        formData.setProcessInstanceId(task.getProcessInstanceId());

        List<FormData> formDataList = formDataService.selectList(formData);

        // 将表单 存入 activiti 中
        Map<String, Object> map = formDataDtos.stream()
                .collect(Collectors.toMap(FormDataDto::getControlId, formDataDto1 ->
                        switch (formDataDto1.getControlType()) {
                            case "s" -> formDataDto1.getControlValue();
                            case "b" -> BooleanUtil.toBoolean(formDataDto1.getControlValue());
                            case "t" -> {
                                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                yield LocalDateTime.parse(formDataDto1.getControlValue(), formatter);
                            }
                            default -> throw new IllegalStateException("未知数据: " + formDataDto1.getControlValue());
                        })
                );

        // 完成任务构建器
        CompleteTaskPayloadBuilder completeTaskPayloadBuilder = TaskPayloadBuilder.complete()
                .withTaskId(formDataDto.getTaskId());
        // 存储表单数据
        if (!map.isEmpty()) {
            completeTaskPayloadBuilder.withVariables(map);
        }
        // 完成任务
        taskRuntime.complete(completeTaskPayloadBuilder.build());

        // 入库
        List<FormData> list = formDataDtos.stream().map(formdata ->
                new FormData(formKey, processDefinitionId, processInstanceId, formdata.getControlId(),
                        formdata.getControlValue())).toList();
        formDataService.saveBatch(list);

        return ResponseEntity.ok("动态表单已保存");
    }
}